package com.yeyks.util;

import org.springframework.beans.BeanUtils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author fuchangshuai
 * @time 2019/2/22 7:48 PM
 */
public class ObjectConvertUtil {

    /**
     * 把source对象转换成另一个clazz类型的对象, 两种对象相同属性的类型，必须相同，否则会抛出BeansException异常。
     * 内部采用BeanUtils.copyProperties(source, object)来实现属性复制。
     *
     * @param source	源对象
     * @param clazz		目标对象的类型
     * @return
     */
    public static <T> T convertObject(Object source, Class<T> clazz) {
        if (source == null) {
            return null;
        }

        T object = BeanUtils.instantiate(clazz);
        BeanUtils.copyProperties(source, object);
        return object;
    }

    /**
     * 拷贝list,只支持List<Object>结构；不支持list里面的元素为集合类型
     *
     * @param source	源list数据
     * @param clazz		需要转换成的list元素类型
     * @return	转换后的列表对象
     */
    public static <T> List<T> convertList(List<?> source, Class<T> clazz) {
        if (source == null) {
            return null;
        }

        List<T> list = new ArrayList<T>();
        for (Object element : source) {
            list.add(convertObject(element, clazz));
        }
        return list;
    }

    /**
     * 字符串列表转换为整型列表
     * @param values 字符串列表
     * @return 整型列表
     */
    public static List<Long> convertList(List<String> values) {
        List<Long> result = new ArrayList<>();
        for (String value : values) {
            result.add(Long.valueOf(value));
        }
        return result;
    }

    public static Map<String, Object> objectToMap(Object obj) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            BeanInfo info = Introspector.getBeanInfo(obj.getClass());
            for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
                Method reader = pd.getReadMethod();
                if (reader != null && !pd.getName().equals("class")) {
                    result.put(pd.getName(), reader.invoke(obj));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return result;
    }
}
